/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package crawler.model;

import business.service.MongoDbFactory;
import com.google.common.base.Joiner;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import crawler.common.ProfileData;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.log4j.Logger;
import org.bson.types.ObjectId;

/**
 *
 * @author ngotandieu
 */
public class ProfileModel {

    private static final String PROFILE_COLLECTION = "profile";

    private static final Logger logger = Logger.getLogger(ProfileModel.class);
    private static final Lock createLock_ = new ReentrantLock();
    private static ProfileModel _instance = null;

    public static ProfileModel getInstance() {
        if (_instance == null) {
            createLock_.lock();
            try {
                if (_instance == null) {
                    _instance = new ProfileModel();

                }
            } finally {
                createLock_.unlock();
            }
        }
        return _instance;
    }

    public ProfileModel() {
        try {
        } catch (Exception ex) {
            logger.error("PostModel: " + ex);
        }
    }

    public List<ProfileData> getProfile(int start, int limit) {
        List<ProfileData> lstProfile = null;
        try {
            BasicDBObject basicDBObject = new BasicDBObject("name", 1);
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(PROFILE_COLLECTION);
            DBCursor cursor = coll.find().sort(basicDBObject);

            if (limit != -1) {
                cursor = cursor.skip(start).limit(limit);
            }

            lstProfile = new ArrayList<>();
            while (cursor.hasNext()) {
                DBObject dbObject = cursor.next();
                String objectId = ((ObjectId) dbObject.get("_id")).toString();
                String name = (String) dbObject.get("name");
                String realname = (String) dbObject.get("realname");
                String avatar = (String) dbObject.get("avatar");
                long dob = (long) dbObject.get("dob");
                String country = (String) dbObject.get("country");
                String profile = (String) dbObject.get("profile");
                String editor = (String) dbObject.get("editor");
                String author = (String) dbObject.get("author");
                long updated = (long) dbObject.get("updated");
                long created = (long) dbObject.get("created");
                String cates = (String) dbObject.get("cates");
                List<String> lstCates;
                if(cates != null && !cates.isEmpty()) {
                    lstCates =  Arrays.asList(cates.split("\\s*,\\s*"));
                } else 
                    lstCates = new ArrayList<>();
                ProfileData appsData = new ProfileData(objectId, name, realname, avatar, dob, country, profile, lstCates, author, editor, updated, created);
                lstProfile.add(appsData);
            }
        } catch (Exception ex) {
            logger.error("ProfileModel.getProfile: " + ex.getMessage(), ex);
        }
        return lstProfile;
    }

    public ProfileData getProfileById(String id) {
        try {
            BasicDBObject basicDBObject = new BasicDBObject("_id", new ObjectId(id));
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(PROFILE_COLLECTION);
            DBCursor cursor = coll.find(basicDBObject);
            if (cursor.hasNext()) {
                DBObject dbObject = cursor.next();
                String objectId = ((ObjectId) dbObject.get("_id")).toString();
                String name = (String) dbObject.get("name");
                String realname = (String) dbObject.get("realname");
                String avatar = (String) dbObject.get("avatar");
                long dob = (long) dbObject.get("dob");
                String country = (String) dbObject.get("country");
                String profile = (String) dbObject.get("profile");
                String editor = (String) dbObject.get("editor");
                String author = (String) dbObject.get("author");
                long updated = (long) dbObject.get("updated");
                long created = (long) dbObject.get("created");
                String cates = (String) dbObject.get("cates");
                List<String> lstCates;
                if(cates != null && !cates.isEmpty()) {
                    lstCates =  Arrays.asList(cates.split("\\s*,\\s*"));
                } else 
                    lstCates = new ArrayList<>();
                ProfileData profileData = new ProfileData(objectId, name, realname, avatar, dob, country, profile, lstCates, author, editor, updated, created);

                return profileData;
            }
        } catch (Exception ex) {
            logger.error("PostModel.getPostById: " + ex.getMessage(), ex);
        }
        return null;
    }

    public long getProfileCount() {
        long count = 0;
        try {
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(PROFILE_COLLECTION);
            count = coll.getCount();
        } catch (Exception ex) {
            logger.error("PostModel.getPostCount: " + ex.getMessage(), ex);
        }
        return count;
    }

    public boolean deleteProfile(String id) {
        try {
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(PROFILE_COLLECTION);
            coll.remove(new BasicDBObject("_id", new ObjectId(id)));

            return true;
        } catch (Exception ex) {
            logger.error("CateModel.deleteCate: " + ex.getMessage(), ex);
        }
        return false;
    }

    public String addProfile(ProfileData profileData) {
        String id = "";
        try {
            BasicDBObject basicDBObject = new BasicDBObject()
                    .append("name", profileData.getName())
                    .append("realname", profileData.getRealname())
                    .append("avatar", profileData.getAvatar())
                    .append("dob", profileData.getDob())
                    .append("country", profileData.getCountry())
                    .append("profile", profileData.getProfile())
                    .append("cates", Joiner.on(",").join(profileData.getCates()))
                    .append("editor", profileData.getEditor())
                    .append("updated", profileData.getUpdated())
                    .append("author", profileData.getAuthor())
                    .append("created", profileData.getCreated());

            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(PROFILE_COLLECTION);
            coll.insert(basicDBObject);

            ObjectId objectId = (ObjectId) basicDBObject.get("_id");
            id = objectId.toString();
        } catch (Exception ex) {
            logger.error("ProfileModel.addProfile: " + ex.getMessage());
        }
        return id;
    }

    public boolean updateProfile(ProfileData profileData) {
        try {
            BasicDBObject basicDBObject = new BasicDBObject()
                    .append("name", profileData.getName())
                    .append("realname", profileData.getRealname())
                    .append("avatar", profileData.getAvatar())
                    .append("dob", profileData.getDob())
                    .append("country", profileData.getCountry())
                    .append("profile", profileData.getProfile())
                    .append("cates", Joiner.on(",").join(profileData.getCates()))
                    .append("editor", profileData.getEditor())
                    .append("updated", profileData.getUpdated())
                    .append("author", profileData.getAuthor())
                    .append("created", profileData.getCreated());

            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(PROFILE_COLLECTION);
            
            BasicDBObject updateDBObject = new BasicDBObject("$set", basicDBObject);
            BasicDBObject searchDBQuery = new BasicDBObject("_id", new ObjectId(profileData.getId()));
            coll.update(searchDBQuery, updateDBObject);
            return true;
        } catch (Exception ex) {
            logger.error("ProfileModel.updateProfile: " + ex.getMessage());
        }
        return false;
    }

    public List<ProfileData> getRelatedProfile(String id, int start, int limit) {
        List<ProfileData> lstProfile = null;
        try {
            BasicDBObject basicDBObject = new BasicDBObject("_id", -1);
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(PROFILE_COLLECTION);
            DBCursor cursor = coll.find().sort(basicDBObject);

            if (!id.equalsIgnoreCase("")) {
                ObjectId objectId = new ObjectId(id);
                int timestamp = objectId.getTimestamp();
                cursor = coll.find(new BasicDBObject("created", new BasicDBObject("$gt", timestamp))).sort(basicDBObject);
            }

            if (limit != -1) {
                cursor = cursor.skip(start).limit(limit);
            }

            lstProfile = new ArrayList<>();
            while (cursor.hasNext()) {
                DBObject dbObject = cursor.next();
                String objectId = ((ObjectId) dbObject.get("_id")).toString();
                String name = (String) dbObject.get("name");
                String realname = (String) dbObject.get("realname");
                String avatar = (String) dbObject.get("avatar");
                long dob = (long) dbObject.get("dob");
                String country = (String) dbObject.get("country");
                String profile = (String) dbObject.get("profile");
                String editor = (String) dbObject.get("editor");
                String author = (String) dbObject.get("author");
                long updated = (long) dbObject.get("updated");
                long created = (long) dbObject.get("created");
                String cates = (String) dbObject.get("cates");
                List<String> lstCates;
                if(cates != null && !cates.isEmpty()) {
                    lstCates =  Arrays.asList(cates.split("\\s*,\\s*"));
                } else 
                    lstCates = new ArrayList<>();
                ProfileData appsData = new ProfileData(objectId, name, realname, avatar, dob, country, profile, lstCates, author, editor, updated, created);
                lstProfile.add(appsData);
            }
        } catch (Exception ex) {
            logger.error("ProfileModel.getRelatedProfile: " + ex.getMessage(), ex);
        }
        return lstProfile;
    }
    
    public boolean setCateForProfile(String profileId, List<String> lstCats) {
        try {
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(PROFILE_COLLECTION);
            
            String cates = Joiner.on(",").join(lstCats);
            BasicDBObject basicDBObject = new BasicDBObject("cates", cates);
            
            BasicDBObject updateDBObject = new BasicDBObject("$set", basicDBObject);
            BasicDBObject searchDBQuery = new BasicDBObject("_id", new ObjectId(profileId));
            coll.update(searchDBQuery, updateDBObject);
            return true;
        } catch (Exception ex) {
            logger.error("ProfileModel.setCateForProfile: " + ex.getMessage(), ex);
        } finally {
            
        }
        return false;
    }
}
